revisto [Tue, 16 Dec 2025 15:58:59 +0000 (19:28 +0330)]
status/volume: Use default color for muted microphone indicator
The muted indicator status is currently hard to distinguish from the
unmuted one. As there is no privacy concern when muted, don't apply
the privacy-indicator styling in that state so the states become
more distinct.
Hari Rana [Sat, 13 Dec 2025 03:36:57 +0000 (22:36 -0500)]
overviewControls: Use ease-out-sine when entering overview and app grid
Using animations with slower initial curves on display-wide
layout shifts may provide a smoother experience to users of
low(er) refresh rate and/or large(r) displays, as they avoid
skipping large chunks of frames, making it less choppy at
the beginning of the animation.
screenShield: Fix user deselection after idle in greeter
When the session goes idle, _maybeCancelDialog() cancels any ongoing
authentication dialog. Commit b16ee1a added code to grab focus after
cancellation, ensuring it stayed on the lock screen curtain rather than
wherever cancel() placed it. This was needed to handle keyboard events
like Enter to raise the unlock dialog.
Commit 727c84251 changed this to grab focus on the dialog itself, since
the lock screen architecture had evolved. However, in the greeter case
there is no separate curtain - the LoginDialog is shown directly and
cancel() already restores focus to the user list via _showUserList().
The additional focus grab on the dialog container moved focus away from
the selected user as soon as the screen began to dim, causing the
username to appear deselected when returning from idle.
Similarly, _ensureUnlockDialog() and _resetLockScreen() grabbed focus on
the dialog container when the screen fully blanked, causing the same
issue.
For the greeter, replace grab_key_focus() with activate(), which
delegates to LoginDialog.activate() and properly focuses the user list.
For the unlock dialog, keep the original grab_key_focus() behavior -
calling UnlockDialog.activate() would invoke _showPrompt(), which would
interfere with commit 4bfa30085 that returns to the clock view after
suspend.
Florian Müllner [Thu, 13 Nov 2025 19:01:04 +0000 (20:01 +0100)]
status/powerProfiles: Indicate non-default power mode in top bar
It is quite easy to switch the power profile for some specific
purpose, and then forgetting to change it back and experiencing
unexpected performance behavior later.
To help with that, indicate the active power profile in the top
bar if it diverges from the default 'balanced' one.
Florian Müllner [Thu, 13 Nov 2025 19:13:37 +0000 (20:13 +0100)]
panel: Move power profiles indicator next to the system one
For devices with a battery, the system indicator shows the current
charge level. As power profiles are related to power, it makes sense
to keep the two indicators next to each other.
Florian Müllner [Tue, 9 Dec 2025 13:33:38 +0000 (14:33 +0100)]
swipeTracker: Handle touchpad gestures on actor
Touchscreen gestures and scrolling are already handled by events
on the associated actor rather than the stage. There's no good
reason to not do the same for touchpad gestures as well.
Florian Müllner [Fri, 5 Dec 2025 09:06:32 +0000 (10:06 +0100)]
workspaceAnimation: Use separate WorkspaceBackground class
Separating WorkspaceGroup and WorkspaceBackground allows each to
track its own set of windows without special-casing exceptions.
This will also give us more flexibility in the future, if we need
to reuse the background elsewhere. This may happen if we optionally
change the animation to a crossfade for the new `reduced-motion`
setting.
Florian Müllner [Fri, 5 Dec 2025 08:25:30 +0000 (09:25 +0100)]
workspaceAnimation: Split out BaseWorkspaceGroup
Since we started to show DESKTOP windows as part of the background
during the workspace animation, we need to track both the windows
relevant for the monitor/workspace and DESKTOP windows.
We are about to split out the background handling into its own class.
To prepare for this, split out a BaseWorkspaceGroup class that handles the
basic "create clones of relevant windows and track them" functionality
common to both cases.
environment: Ignore animation events after shutdown
As soon as the shutdown starts, any animation event does not make sense,
although during this phase the clutter timelines may still proceed and
potentially calling invalid code in their callbacks.
Prevent this from happening by disconnecting from any timeline signal
we are connected to as soon as the `shutdown` signal is emitted
Ian Off [Thu, 21 Aug 2025 04:27:43 +0000 (23:27 -0500)]
screenshot: End screencast with same keybinding as start screencast
Currently, the screencast keyboard shortcut shows the UI to begin a
screencast, but there is no way to end it with a keyboard shortcut.
This behavior is inconvenient and seems to be a regression, as a wide
variety of online resources recommend using the same shortcut to start
and end screencasts.
This commit introduces a simple check when the showScreenRecordingUI
function is called by the show-screen-recording-ui keybinding.
If the showScreenRecordingUI function is called while a screencast
is in progress, the stopScreencast function is called instead
of opening the screenshot UI in screencast mode.
environment: Generalize easeActorProperty to animatable case
We're not handling actors only with it but also St.Adjustment that is a
Clutter.Animatable, so let's name it for what it is, and adjust the
parameter so that its type is not given for granted
overviewControls: Wait for all animation promises on startup
Currently on startup we're just waiting for a single animation (the dash
one) being completed, while this is acceptable since the animation
duration is not shorter or longer than others, it's still not clean, as
technically we should just wait for all the pending animations of the
set before calling the startup animation completed.
Florian Müllner [Fri, 28 Nov 2025 00:43:33 +0000 (01:43 +0100)]
layout: Resolve immediately after loading the background
We currently resolve the promise in a low-priority idle handler
after the background was loaded, so that the system can settle
down after the initial load before doing the animation.
Promises are already resolved on the main loop (albeit with
a high priority), so hopefully the explicit idle source isn't
necessary anymore.
Florian Müllner [Fri, 28 Nov 2025 00:13:29 +0000 (01:13 +0100)]
layout: Use promise to wait for background to load
This allows us to separate the end of the loading operation
from the steps that follow it. We will soon use that to
express the startup animation as a series of (async) steps
instead of a chain of function calls.
Florian Müllner [Thu, 27 Nov 2025 21:47:46 +0000 (22:47 +0100)]
layout: Use promise to ensure primary monitor
Both loading the system background and setting up the startup animation
depends on having a primary monitor, so we wait for the monitor to
appear if necessary.
Currently this is done differently in each case, once by having a hook
to recall a method when the monitor appears, and once by re-running an
idle handler.
Replace this with an async `_ensurePrimaryMonitor()` method that we can
use to await the primary monitor where needed.
Debarshi Ray [Fri, 28 Nov 2025 21:24:17 +0000 (22:24 +0100)]
ci: Clean up the dependencies
The pkgconfig(gobject-introspection-1.0) dependency was added in commit 0a420404c603 ("ci: Update JS tooling") as a build-time dependency of gjs
at the time time, even though it wasn't being built from source, and the
pre-built gjs included in the image was being used.
What's needed is a C compiler to build gnome-extensions-tool, and GCC
was being pulled in by pkgconfig(gobject-introspection-1.0) through
libtool.
Lukas Schmelting [Thu, 27 Nov 2025 22:58:32 +0000 (23:58 +0100)]
screenShield: Avoid unfocused authentication view after resume
When suspending on the authentication page of the lock screen in a user
session, the session resumes with the authentication dialog shown but
its password entry field unfocused. Instead, focus moves to the
authentication dialog itself while _ensureUnlockDialog() in
screenShield.js is called on resume.
Avoid this edge case by switching to the clock view instead before
suspend, which also provides a more consistent user experience.
messageTray: Disconnect to global signals on destruction
The global display object has always a longer lifetime than anything
that is initialized from JS, so avoid signals that it may emit to be
handled at later point.
It handles issues such as:
(gnome-shell:2429): Gjs-CRITICAL **: 23:18:35.025: Object
Gjs_ui_messageTray_MessageTray (0x3440ed60), has been already disposed —
impossible to set any property on it.
This might be caused by the object having been destroyed from C code using
something such as destroy(), dispose(), or remove() vfuncs.
== Stack trace for context 0x31073eb0 ==
#0 348db378 i resource:///org/gnome/shell/ui/messageTray.js:1046 (3a8ac3a71f60 @ 104)
#1 348db2d8 i resource:///org/gnome/shell/ui/main.js:277 (3a8ac3a0b100 @ 119)
Seen in: https://gitlab.gnome.org/GNOME/gnome-shell/-/jobs/5846454
Florian Müllner [Thu, 27 Nov 2025 15:29:44 +0000 (16:29 +0100)]
test-tool: Set up GSettings keyfile
Even with a separate XDG_CONFIG_HOME, settings may still be picked
up from the session's dconf instance (although the tool is typically
run through dbus-run-session).
To really ensure that we control the settings, we can force a different
backend. The 'memory' backend would be enough to ensure default values,
however using the 'keyfile' backend means we can also inject non-default
values.
Florian Müllner [Thu, 27 Nov 2025 13:43:43 +0000 (14:43 +0100)]
test-tool: Set up a temporary xdg-home directory
Currently the launched gnome-shell instance uses the regular xdg-home
directories, which means it picks up settings, extensions etc. from
the current user.
Avoid this by pointing the xdg-home dirs to a temporary directory, so
everything that respects the basedir spec runs with a clean slate.
Florian Müllner [Thu, 27 Nov 2025 14:06:12 +0000 (15:06 +0100)]
test-tool: Remove option to upload perf reports
If memory serves well, uploads happened to a server in Owen's living
room. It is doubtful that the server-side still exists anywhere, or
that anyone has uploaded any reports in the last 15 years, so stop
carrying that code around.
Florian Müllner [Thu, 27 Nov 2025 14:41:44 +0000 (15:41 +0100)]
test-tool: Adjust name in --version
The tool was renamed from "perf-tool" a while ago, to reflect
that its purpose has shifted from collecting performance data
to running gnome-shell with scripted tests.
We are using it in overviewControls but the value is not exported.
This caused an issue when the animations are not enabled, since in a
racy way (e.g. only sometimes, depending on the init speed) the value
was undefined, and so we ended up falling back to the default animation
duration time.
In case an actor easing is created without an explicit duration, we
should rely to the default animation that Clutter.Actor.save_easing_state()
sets to 250ms.
This fine in normal use cases, but in case the animations are disabled
the current code skips calling our Clutter.Actor.set_easing_duration()
override, and so we just end up leaving the actor easing time to 250ms,
not respecting the St settings
Carlos Garnacho [Fri, 21 Nov 2025 13:46:03 +0000 (14:46 +0100)]
screenShield: Emit ::screen-lock-shown early with animated fades
If the screen is locked with animatedFade parameter enabled, the
screenShield currently defers the emission of this signal until the
lightbox toggles on. However the lightbox might be prevented from
ever doing that by later input.
If this emission is delayed enough, it will result in ShellDBus
missing the D-Bus timeout for replying to the Lock request, since
it does rely on this signal being emitted in order to reply back.
It does however make sense to keep setting the active state after
the animation, so the inhibitors are synchronized at the point the
lightbox kicks in.
Florian Müllner [Thu, 20 Nov 2025 15:09:44 +0000 (16:09 +0100)]
swipeTracker: Immediately flip delta in RTL locales
The delta is currently flipped in a shared code path, after appending
the unmodified value to the event history. As a result, the calculated
final velocity for touchpad gestures is wrong in RTL locales.
Fix this by modifying the delta immediately when handling the events,
so that all other code operates on the correct values.
Philip Withnall [Tue, 11 Nov 2025 15:31:22 +0000 (15:31 +0000)]
timeLimitsManager: Batch-submit usage records to malcontent-timerd
This was skipped in the first version of parental controls screen time
limits, because we forgot that `RecordUsage()` already allows batch
submission of usage records.
Rework the code to make one D-Bus call rather than O(N) calls.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3958>
The LongPressGesture 'may-recognize' callback in commit 314137c8c was
checking if clicks were inside '_switcherList', but thumbnails shown by
switch-group are siblings of _switcherList, not children.
This caused the gesture to incorrectly identify thumbnail clicks as
'outside' clicks, closing the popup before the click could complete.
Fix by adding a _isActorOutside() helper method that subclasses can
override to check additional containers. AppSwitcherPopup now properly
checks both _switcherList and _thumbnails.
Tested on Ubuntu 25.10 with GNOME Shell 49.0. Confirmed:
- switch-group mouse clicks now work
- switch-applications and switch-windows unaffected
- clicking outside the popup still closes it correctly
- no regressions introduced
Fixes: 314137c8c9 ("switcherPopup: Move to a ClutterGesture for closing the popup") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8812
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3959>
Adrian Vovk [Thu, 1 May 2025 22:34:52 +0000 (18:34 -0400)]
main: Register session with GDM on startup
When no monitor is connected, gnome-shell starts but never emits
`startup-prepared` nor `startup-complete`. As a result, GDM never
detects that the shell has launched and plymouthd remains running,
preventing the system from reaching graphical.target.
Ensure that registerSessionWithGDM() is called even when no monitor
is connected, so GDM can terminate plymouthd and allow the system to
reach graphical.target properly.
Part of https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/285
timeLimitsManager: Integrate with malcontent and lock when limit reached
Lock the screen when screen time limit is reached in a child session,
which required extending the existing TimeLimitsManager functionality to
include the parental controls session limits.
TimeLimitsDispatcher was also adjusted to take into account parental
controls session limits before making any user facing changes.
timeLimitsManager: Rename function updating state machine
Rename _updateSettings function to _updateStateMachine, since that's
what the function actually does, starting or stopping the machine
depending on the 'history-enabled' GSetting. Moreover, in the future
we'll take into account parental controls settings too, so renaming the
function to be more generic will avoid confusion later on.
tests/unit: Add a helper method in TimeLimitsManager
Currently we create a new `TimeLimitsManager` for each of the unit tests
for testing the wellbeing screen time limit, with the same parameters.
Rather than having to repeat the entire constructor call multiple times,
factor it out into a helper method on the `TestHarness`. There is no
difference in functionality itself.
Add org.freedesktop.MalcontentTimer1.Child interface for accessing the
screen time and app usage periods for current user account. Currently
unused, will provide necessary functionality when integrating parental
controls session limits with TimeLimitsManager.
parentalControlsManager: Add support for session limits
Add ability to check if session limits are enabled for users using API
introduced in malcontent 0.14.0. The `get_session_limits_async` function
is actually available since 0.5.0, but the signal
`session-limits-changed` was only introduced in 0.14.0, so check for
function `get_daily_limit` which was introduced in 0.14.0 to be sure
we're using correct version. This allows us to keep filtering apps, even
if the library version doesn't fully support session limits.
Will be used in the future to integrate parental controls session
limits.
Carlos Garnacho [Wed, 8 Oct 2025 18:36:39 +0000 (20:36 +0200)]
grabHelper: Port to using ClickGesture to dismiss
There's a few things we don't need anymore here. We don't
need holding on the captured events until button release
anymore, and we don't need to track crossing events outside
the grab as those will not get emitted as usual. This allows
for a few simplifications in handling the events for the
GrabHelper.
Carlos Garnacho [Wed, 8 Oct 2025 17:37:04 +0000 (19:37 +0200)]
searchController: Maybe reset search using a click gesture
We don't want the gesture to consume input though, we just want
it as a trigger on click, so use the ::may-recognize signal to
hook this "reset, but passthrough" behavior on.
We are currently still using eslint 8.x which has been unsupported
for quite a while. Update the ci-run-eslint script to a verison
that uses the supported eslint 9.x.
There's no reason why this is not the case, given that these tests are
running in completely separated environments, so they are safe to run in
parallel